package cn.schoolwow.util.module.crypto.messageDigest.flow;

import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.util.domain.check.instance.CheckInstance;
import cn.schoolwow.util.module.crypto.common.flow.ByteToStringFlow;
import cn.schoolwow.util.module.crypto.messageDigest.domain.MessageDigestOption;

import java.io.FileInputStream;
import java.security.MessageDigest;

public class GetMessageDigestHexFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        String type = flowContext.checkData("type", String.class);

        checkMessageDigestOptionFlow(flowContext);
        switch (type){
            case "data":{data(flowContext);}break;
            case "file":{file(flowContext);}break;
        }
    }

    @Override
    public String name() {
        return "获取数据散列值";
    }

    private void checkMessageDigestOptionFlow(FlowContext flowContext) throws Exception{
        MessageDigestOption messageDigestOption = flowContext.checkInstanceData(MessageDigestOption.class);
        String type = flowContext.checkData("type", String.class);

        CheckInstance.newCheck()
                .notNullCheck(messageDigestOption.messageDigestType, "散列算法");
        switch (type){
            case "data":{
                CheckInstance.newCheck()
                        .notEmptyCheck(messageDigestOption.data, "数据");
            }break;
            case "file":{
                CheckInstance.newCheck()
                        .notNullCheck(messageDigestOption.file, "文件");
            }break;
        }
        MessageDigest md = null;
        switch (messageDigestOption.messageDigestType){
            case MD5:{
                md = MessageDigest.getInstance("MD5");
            }break;
            case SHA1:{
                md = MessageDigest.getInstance("SHA-1");
            }break;
            case SHA256:{
                md = MessageDigest.getInstance("SHA-256");
            }break;
            case SHA512:{
                md = MessageDigest.getInstance("SHA-512");
            }break;
            default:{
                throw new IllegalArgumentException("不支持的散列算法!算法名称:"+messageDigestOption.messageDigestType.name());
            }
        }
        flowContext.putCurrentFlowInstanceData(md, MessageDigest.class);
    }

    private void data(FlowContext flowContext){
        MessageDigest messageDigest = flowContext.checkInstanceData(MessageDigest.class);
        MessageDigestOption messageDigestOption = flowContext.checkInstanceData(MessageDigestOption.class);

        byte[] digest = messageDigest.digest(messageDigestOption.data);

        flowContext.startFlow(new ByteToStringFlow())
                .putCurrentCompositeFlowData("bytes", digest)
                .execute();
    }

    private void file(FlowContext flowContext) throws Exception{
        MessageDigest messageDigest = flowContext.checkInstanceData(MessageDigest.class);
        MessageDigestOption messageDigestOption = flowContext.checkInstanceData(MessageDigestOption.class);

        try (FileInputStream fis = new FileInputStream(messageDigestOption.file)) {
            byte[] byteArray = new byte[1024];
            int bytesCount;
            while ((bytesCount = fis.read(byteArray)) != -1) {
                messageDigest.update(byteArray, 0, bytesCount);
            }
        }
        byte[] bytes = messageDigest.digest();
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
        }
        flowContext.putTemporaryData("string", sb.toString());
    }
}
